//模板引擎的实现文件
import Watch from "./observe/watcher";
import { createElementVNode, createTextNode } from "./vdom/index";
import { patch } from "./vdom/patch";

export function initLifeCycle(Vue) {
  Vue.prototype._update = function(vnode) { //vnode这个是虚拟DOM
    // console.log("update", vnode); //这个是虚拟DOM
    const vm = this;
    const el = vm.$el;
 
    //diff算法逻辑处理
    const prevVnode = vm._vnode;
    vm._vnode = vnode;
    if(prevVnode) {
      vm.$el = patch(prevVnode,vnode);//patch既有初始化功能和更新功能
    }else {
      vm.$el = patch(el, vnode);
    }
   
  }
  // _c _v _s 都是为了把获取来的数据变成相要的格式
  Vue.prototype._c = function() {
    return createElementVNode(this, ...arguments);
  }
  Vue.prototype._v = function() {
    return createTextNode(this, ...arguments)
  }
  Vue.prototype._s = function(value) {
    if(typeof value !== 'object') return value
    return JSON.stringify(value);
  }
  Vue.prototype._render = function() {
    return this.$options.render.call(this);
  }
}
export function mountComponent(vm, el) {
  vm.$el = el;
  //vm._render() 作用是生成虚拟结点
  //vm._render()返回的是虚拟DOM
  //vm._update作用是把虚拟结点转成真实的DOM结点
  const updateComponent = () => { //updateComponent更新视图的函数
    vm._update(vm._render());
  }
  new Watch(vm, updateComponent,true); //true代表渲染过程
}
/**
 *  vue核心流程: 
 *     1) 创造了响应式数据 
 *     2)模板转换成ast语法树
 *     3)将ast语法树转换了render函数 
 *     4)后续每次数据更新可以只执行render函数(无需再次执行ast转化的过程) 
 *       
 * render函数会去产生虚拟节点(使用响应式数据)
 * 根据生成的虚拟节点创造真实的DOM
 */


